import { isNil, isEmpty, isPlainObject, isString, isFunction } from 'lodash-es';
import { DATE_LIST, INPUT_LIST, INPUT_TYPE_LIST } from './enums';

export const isPromise = (value) => {
  return value && isFunction(value.then);
};
export function useEvents({ props, events, emit, form }) {
  return events.reduce((acc, event) => {
    if (!isPlainObject(event) && !isString(event)) {
      throw new Error('event must be object or string');
    }
    if (isString(event)) {
      event = { name: event };
    }
    const { name, callback } = event;
    const eventHandler = props[name];

    acc[name] = (...args) => {
      if (typeof eventHandler === 'function') {
        eventHandler(...args, { form: form, dic: props.dic });
      }
      emit(name, ...args);
      if (callback) {
        callback();
      }
    };
    return acc;
  }, {});
}

export function useVSlots(props, slots) {
  return computed(() => {
    const res = {};
    const prefix = `${props.prop}-`;
    for (const key in slots) {
      if (key.startsWith(prefix)) {
        const newKey = key.replace(new RegExp(`^${prefix}`), '');
        res[newKey] = key;
      }
    }
    return res;
  });
}
export function getComponent(column) {
  const { type, component } = column;
  const KEY_COMPONENT_NAME = 'su-';
  let res = type || 'input';
  if (!isEmpty(component)) {
    return component;
  } else if (DATE_LIST.includes(type)) {
    res = 'date';
  } else if (INPUT_LIST.includes(type)) {
    res = 'input';
  }
  return KEY_COMPONENT_NAME + res;
}

export function getRules(column) {
  const { label, type, rules } = column;
  if (Array.isArray(rules)) {
    return rules.map((rule) => {
      if (rule.required === true) {
        const message = INPUT_TYPE_LIST[type] ? `请输入${label}` : `请选择${label}`; // 使用提炼出的函数
        rule.message ||= message;
      }
      return rule;
    });
  }
  return [];
}
export function getLabel(label, labelSuffix) {
  return isNil(labelSuffix) ? label : `${label}${labelSuffix}`;
}
export function getPlaceholder(column) {
  const { label, type, placeholder } = column;
  if (placeholder) {
    return placeholder;
  } else {
    if (INPUT_TYPE_LIST.includes(type)) {
      return `请输入${label}`;
    } else {
      return `请选择${label}`;
    }
  }
}
export function getSlotName(column = {}, type = '', slots) {
  const name = `${column.prop}-${type}`;
  if (slots) return slots[name];
  return name;
}
export function getColumnSlotName(column = {}, slots) {
  return Object.keys(slots).filter((slotKey) => {
    return slotKey.startsWith(column.prop) && slotKey !== column.prop;
  });
}
export function getSlotMap(column = {}, slots) {
  return Object.keys(slots).reduce((a, k1) => {
    const p = `${column.prop}-`;
    const k2 = k1.replace(new RegExp(`^${p}`), '');
    a[k2] = k1;
    return a;
  }, {});
}
export const toPx = (value) => {
  if (value !== void 0) {
    return isNaN(Number(value)) ? String(value) : `${value}px`;
  }
};

export const invokeBy = (func, { args = {}, done, cancel }) => {
  if (isFunction(func)) {
    const cb = func(args);
    if (isPromise(cb)) {
      cb.then((value) => {
        if (value) {
          done(value);
        } else if (cancel) {
          cancel();
        }
      }).catch(() => {
        if (cancel) {
          cancel();
        }
      });
    } else if (cb) {
      done();
    } else if (cancel) {
      cancel();
    }
  } else {
    done();
  }
};
